package com.hr.剑指offer.work1;

/**
 * @author 周恒哲
 * @date 2020/06/17
 * 算法流程：
 *      1、空值处理： 当 matrix 为空时，直接返回空列表 [] 即可。
 *      2、初始化： 矩阵 左、右、上、下 四个边界 l , r , t , b ，用于打印的结果列表 res 。
 *      3、循环打印： "从左向右、从上向下、从右向左、从下向上" 四个方向循环，每个方向打印中做以下三件事 （各方向的具体信息见下表） ；
 *          根据边界打印，即将元素按顺序添加至列表 res 尾部；
 *          边界向内收缩 1 （代表已被打印）；
 *          判断是否打印完毕（边界是否相遇），若打印完毕则跳出。
 *      4、返回值： 返回 res 即可。
 *             打印方向	    1. 根据边界打印	        2. 边界向内收缩	        3. 是否打印完毕
 *             从左向右	    左边界l ，右边界 r	    上边界 t 加 1	        是否 t > b
 *             从上向下	    上边界 t ，下边界b	    右边界 r 减 1	        是否 l > r
 *             从右向左	    右边界 r ，左边界l	    下边界 b 减 1	        是否 t > b
 *             从下向上	    下边界 b ，上边界t	    左边界 l 加 1	        是否 l > r
 **/
public class 面试题29_顺时针打印矩阵 {
    public int[] spiralOrder(int[][] matrix) {
        if (matrix.length==0){
            return new int[0];
        }
        int l=0;//左边界l
        int r=matrix[0].length-1;//右边界 r
        int t=0;//上边界t
        int b=matrix.length-1;//下边界b
        int x=0;
        int[] res=new int[(r+1)*(b+1)];//获取数组长度（长*宽）
        while (true){
            for(int i = l; i <= r; i++) {
                res[x++] = matrix[t][i];// 从左到右
            }
            if(++t > b) {
                break;
            }
            for(int i = t; i <= b; i++) {
                res[x++] = matrix[i][r]; // 从上到下
            }
            if(l > --r) break;
            for(int i = r; i >= l; i--) {
                res[x++] = matrix[b][i]; // 从右到上
            }
            if(t > --b) {
                break;
            }
            for(int i = b; i >= t; i--) {
                res[x++] = matrix[i][l]; // 从下到上
            }
            if(++l > r) {
                break;
            }
        }
        return res;
    }
}
